﻿using Coldairarrow.Entity.MEGA;
using Coldairarrow.IBusiness;
using Coldairarrow.Util;
using EFCore.Sharding;
using LinqKit;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Hosting;
using SelectPdf;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using ThoughtWorks.QRCode.Codec;

namespace Coldairarrow.Business.MEGA
{
    public class MEGA_LeafBladeBusiness : BaseBusiness<MEGA_LeafBlade>, IMEGA_LeafBladeBusiness, ITransientDependency
    {
        readonly IOperator _operator;
        readonly IHostingEnvironment _hostingEnv;
        public MEGA_LeafBladeBusiness(IDbAccessor db, IOperator @operator,IHostingEnvironment hostingEnv)
            : base(db)
        {
            _operator = @operator;
            _hostingEnv = hostingEnv;
        }

        #region 外部接口

        public async Task<PageResult<MEGA_LeafBladeDTO>> GetDataListAsync(PageInput<ConditionDTO> input)
        {
            var q = GetIQueryable();
            var where = LinqHelper.True<MEGA_LeafBlade>();
            var search = input.Search;
            //筛选
            //if (!search.Condition.IsNullOrEmpty() && !search.Keyword.IsNullOrEmpty())
            //{
            //    var newWhere = DynamicExpressionParser.ParseLambda<MEGA_LeafBlade, bool>(
            //        ParsingConfig.Default, false, $@"{search.Condition}.Contains(@0)", search.Keyword);
            //    where = where.And(newWhere);
            //}
            if (!search.Keyword.IsNullOrEmpty())
            {
                if (search.Keyword.Contains("未"))
                {
                    q = q.Where(e => e.State == 0);
                }
                else if (search.Keyword.Contains("正在"))
                {
                    q = q.Where(e => e.State == 1);
                }
                else if (search.Keyword.Contains("完成"))
                {
                    q = q.Where(e => e.State == 2);
                }
                else
                {
                    q = q.Where(e => e.Name.Contains(search.Keyword) || e.Length.Contains(search.Keyword) || e.Spec.Contains(search.Keyword) || e.Code.Contains(search.Keyword) || e.Batch.Contains(search.Keyword));
                }     
            }
            q =  q.OrderBy(input.SortField, input.SortType).Where(where);

            List<MEGA_LeafBladeDTO> qq = new List<MEGA_LeafBladeDTO>();
            foreach (var model in q.ToList())
            {
                //工厂ids
                var fids = Db.GetIQueryable<MEGA_LeafBladeAndFactory>(true).Where(x => x.LBId.Equals(model.Id)).Select(x=>x.FId).ToList();

                //加工人ids
                var wids = Db.GetIQueryable<MEGA_LeafBladeAndWorker>(true).Where(x => x.LBId.Equals(model.Id)).Select(x => x.WId).ToList();

                //材料ids
                var mids = Db.GetIQueryable<MEGA_LeafBladeAndMaterial>(true).Where(x => x.LBId.Equals(model.Id)).Select(x => x.MId).ToList();

                MEGA_LeafBladeDTO newmodel = new MEGA_LeafBladeDTO();
                newmodel.Id = model.Id;
                newmodel.AreaId = model.AreaId;
                newmodel.AreaName = model.AreaName;
                newmodel.Code = model.Code;
                newmodel.CreateTime = model.CreateTime;
                newmodel.CreatorId = model.CreatorId;
                newmodel.Deleted = model.Deleted;
                newmodel.Describe = model.Describe;
                newmodel.Editor = model.Editor;
                newmodel.EditTime = model.EditTime;
                newmodel.FactoryIds = fids;
                newmodel.FactoryNames = Db.GetIQueryable<MEGA_FactoryManagement>().Where(e => fids.Contains(e.Id)).Select(x => x.Name).ToList();
                newmodel.Image = model.Image;
                newmodel.Length = model.Length;
                newmodel.MaterialIds = mids;
                newmodel.MaterialNames= Db.GetIQueryable<MEGA_Material>().Where(e => mids.Contains(e.Id)).Select(x => x.Name).ToList();
                //MaterialName = c.Name;
                newmodel.Name = model.Name;
                newmodel.Note = model.Note;
                newmodel.WorkerIds = wids;
                newmodel.WorkerNames = Db.GetIQueryable<MEGA_Worker>().Where(e => wids.Contains(e.Id)).Select(x => x.Name).ToList();
                newmodel.Spec = model.Spec;
                newmodel.Batch = model.Batch;
                newmodel.State = model.State;
                qq.Add(newmodel);
            }

            int count = q.Where(where).Count();
            
             var list = qq
                .Skip((input.PageIndex - 1) * input.PageRows)
                .Take(input.PageRows)
                .ToList();

            return new PageResult<MEGA_LeafBladeDTO> { Data = list, Total = count };

        }

        public async Task<MEGA_LeafBlade> GetTheDataAsync(string id)
        {
            var q = GetIQueryable().Where(x=>x.Id.Equals(id));
            //var qq = (from a in q
            //         join b in Db.GetIQueryable<MEGA_FactoryManagement>() on a.FactoryId equals b.Id
            //         join c in Db.GetIQueryable<MEGA_Material>() on a.MaterialId equals c.Id
            //         select new MEGA_LeafBlade
            //         {
            //             Id = a.Id,
            //             AreaId = a.AreaId,
            //             AreaName = a.AreaName,
            //             Code = a.Code,
            //             CreateTime = a.CreateTime,
            //             CreatorId = a.CreatorId,
            //             Deleted = a.Deleted,
            //             Describe = a.Describe,
            //             Editor = a.Editor,
            //             EditTime = a.EditTime,
            //             FactoryId = a.FactoryId,
            //             FactoryName = b.Name,
            //             Image = a.Image,
            //             Length = a.Length,
            //             MaterialId = a.MaterialId,
            //             MaterialName = c.Name,
            //             Name = a.Name,
            //             Note = a.Note,
            //             PeopleId = a.PeopleId,
            //             PeopleName = a.PeopleName,
            //             Spec = a.Spec,
            //             State = a.State
            //         }).FirstOrDefaultAsync();
            return await q.FirstOrDefaultAsync();
        }

        public async Task AddDataAsync(MEGA_LeafBlade data)
        {
            //string code = DateTime.Now.ToJsTimestamp().ToString().Substring(5, 8);
            ////生成随机8位数字
            //data.Code = "YP" + code;
            var q = Db.GetIQueryable<MEGA_LeafBlade>().Where(x => x.Name.Equals(data.Name)).ToList();
            if (q.Count() > 0)
            {
                throw new Exception("该叶片已经存在!");
            }
            await InsertAsync(data);
        }

        public async Task UpdateDataAsync(MEGA_LeafBlade data)
        {            
            await UpdateAsync(data);
        }

        public async Task DeleteDataAsync(List<string> ids)
        {
            await DeleteAsync(ids);
        }

        public async Task UpdateStateDataAsync(List<StateDTO> input)
        {
            List<MEGA_LeafBlade> list = new List<MEGA_LeafBlade>();
            foreach (var newmodel in input)
            {
                var model = GetEntity(newmodel.id);
                model.State = newmodel.state;
                list.Add(model);
            }
            await UpdateAsync(list);
        }
        /// <summary>
        /// 一个叶片只能绑定一个加工厂
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task SaveTheFactoryAsync(List<MEGA_LeafBladeAndFactory> input)
        {
            List<MEGA_LeafBladeAndFactory> Datalist = new List<MEGA_LeafBladeAndFactory>();
            foreach (var model in input)
            {
                MEGA_LeafBladeAndFactory newmodel = new MEGA_LeafBladeAndFactory();
                newmodel.Id = GuidHelper.GenerateKey();
                newmodel.LBId = model.LBId;
                newmodel.FId = model.FId;
                newmodel.CreateTime = DateTime.Now;
                newmodel.CreatorId = _operator.UserId;
                var q = Db.GetIQueryable<MEGA_LeafBladeAndFactory>().Where(e => e.FId.Equals(model.FId)).ToList();
                if (q.Count() > 0)
                {
                    throw new Exception("该加工厂已被绑定!");
                }
                Datalist.Add(newmodel);
            }
            await Db.InsertAsync<MEGA_LeafBladeAndFactory>(Datalist);
        }

        public async Task SaveMaterialDataAsync(List<MEGA_LeafBladeAndMaterial> input)
        {
            List<MEGA_LeafBladeAndMaterial> list = new List<MEGA_LeafBladeAndMaterial>();
            foreach (var model in input)
            {
                MEGA_LeafBladeAndMaterial newmodel = new MEGA_LeafBladeAndMaterial();
                newmodel.Id = GuidHelper.GenerateKey();
                newmodel.CreateTime = DateTime.Now;
                newmodel.CreatorId = _operator.UserId;
                newmodel.Note = model.Note;
                newmodel.Num = model.Num;
                newmodel.LBId = model.Id;
                newmodel.MId = model.MId;
                newmodel.Deleted = false;
                var q = Db.GetIQueryable<MEGA_LeafBladeAndMaterial>().Where(e => e.LBId.Equals(model.Id) && e.MId.Equals(model.MId)).ToList();
                if (q.Count()>0)
                {
                    continue;
                }
                list.Add(newmodel);
            }

            await Db.InsertAsync<MEGA_LeafBladeAndMaterial>(list);
        }

        public async Task SaveThePeopleDataAsync(List<MEGA_LeafBladeAndWorker> input)
        {
            List<MEGA_LeafBladeAndWorker> list = new List<MEGA_LeafBladeAndWorker>();
            foreach (var model in input)
            {
                MEGA_LeafBladeAndWorker newmodel = new MEGA_LeafBladeAndWorker();
                newmodel.Id = GuidHelper.GenerateKey();
                newmodel.CreateTime = DateTime.Now;
                newmodel.CreatorId = _operator.UserId;
                newmodel.Note = model.Note;
                newmodel.Deleted = false;
                newmodel.LBId = model.Id;
                newmodel.WId = model.WId;
                var q = Db.GetIQueryable<MEGA_LeafBladeAndWorker>().Where(e => e.LBId.Equals(model.Id) && e.WId.Equals(model.WId)).ToList();
                if (q.Count() > 0)
                {
                    continue;
                }
                list.Add(newmodel);
            }

            await Db.InsertAsync<MEGA_LeafBladeAndWorker>(list);
        }


        public async Task<PageResult<MEGA_LeafBladeDTO>> GetOverDataListAsync(PageInput<ConditionDTO> input)
        {
            var q = GetIQueryable().Where(x=>x.State==2);
            var where = LinqHelper.True<MEGA_LeafBlade>();
            var search = input.Search;
            //筛选
            //if (!search.Condition.IsNullOrEmpty() && !search.Keyword.IsNullOrEmpty())
            //{
            //    var newWhere = DynamicExpressionParser.ParseLambda<MEGA_LeafBlade, bool>(
            //        ParsingConfig.Default, false, $@"{search.Condition}.Contains(@0)", search.Keyword);
            //    where = where.And(newWhere);
            //}
            if (!search.Keyword.IsNullOrEmpty())
            {
              q = q.Where(e => e.Name.Contains(search.Keyword) || e.Length.Contains(search.Keyword) || e.Spec.Contains(search.Keyword) || e.Code.Contains(search.Keyword) || e.Batch.Contains(search.Keyword));
            }
            q = q.OrderBy(input.SortField, input.SortType).Where(where);
            List<MEGA_LeafBladeDTO> qq = new List<MEGA_LeafBladeDTO>();
            foreach (var model in q.ToList())
            {
                //工厂ids
                var fids = Db.GetIQueryable<MEGA_LeafBladeAndFactory>(true).Where(x => x.LBId.Equals(model.Id)).Select(x => x.FId).ToList();

                //加工人ids
                var wids = Db.GetIQueryable<MEGA_LeafBladeAndWorker>(true).Where(x => x.LBId.Equals(model.Id)).Select(x => x.WId).ToList();

                //材料ids
                var mids = Db.GetIQueryable<MEGA_LeafBladeAndMaterial>(true).Where(x => x.LBId.Equals(model.Id)).Select(x => x.MId).ToList();

                MEGA_LeafBladeDTO newmodel = new MEGA_LeafBladeDTO();
                newmodel.Id = model.Id;
                newmodel.AreaId = model.AreaId;
                newmodel.AreaName = model.AreaName;
                newmodel.Code = model.Code;
                newmodel.CreateTime = model.CreateTime;
                newmodel.CreatorId = model.CreatorId;
                newmodel.Deleted = model.Deleted;
                newmodel.Describe = model.Describe;
                newmodel.Editor = model.Editor;
                newmodel.EditTime = model.EditTime;
                newmodel.FactoryIds = fids;
                newmodel.FactoryNames = Db.GetIQueryable<MEGA_FactoryManagement>().Where(e => fids.Contains(e.Id)).Select(x => x.Name).ToList();
                newmodel.Image = model.Image;
                newmodel.Length = model.Length;
                newmodel.MaterialIds = mids;
                newmodel.MaterialNames = Db.GetIQueryable<MEGA_Material>().Where(e => mids.Contains(e.Id)).Select(x => x.Name).ToList();
                //MaterialName = c.Name;
                newmodel.Name = model.Name;
                newmodel.Note = model.Note;
                newmodel.WorkerIds = wids;
                newmodel.WorkerNames = Db.GetIQueryable<MEGA_Worker>().Where(e => wids.Contains(e.Id)).Select(x => x.Name).ToList();
                newmodel.Spec = model.Spec;
                newmodel.State = model.State;

                qq.Add(newmodel);
            }

            int count = q.Where(where).Count();

            var list = qq
               .Skip((input.PageIndex - 1) * input.PageRows)
               .Take(input.PageRows)
               .ToList();

            return new PageResult<MEGA_LeafBladeDTO> { Data = list, Total = count };

        }

        public async Task BuildQrCodeDataAsync(List<string> ids)
        {
            List<MEGA_LeafBladeAndQrCode> list = new List<MEGA_LeafBladeAndQrCode>();
            foreach (var id in ids)
            {
                MEGA_LeafBladeAndQrCode model = new MEGA_LeafBladeAndQrCode();
                model.Id = GuidHelper.GenerateKey();
                model.CreateTime = System.DateTime.Now;
                model.CreatorId = _operator.UserId;
                model.LBId = id;
                model.QrCode = SetQrCode(id);
                list.Add(model);
            }
            await Db.InsertAsync<MEGA_LeafBladeAndQrCode>(list);
        }

        /// <summary>
        /// 生成二维码
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        private string SetQrCode(string id)
        {
            var bitmap = QRCodeHelper.BuildQRCode(id);
            MemoryStream ms = new MemoryStream();
            bitmap.Save(ms, ImageFormat.Jpeg);
            string webRootPath = _hostingEnv.ContentRootPath;  //获取项目运行绝对路径
            var path = $"/wwwroot/ExportQrCode/{DateTime.Now.ToString("yyyyMMdd")}/";//文件相对路径
            var savepath = $"{webRootPath}{path}{Guid.NewGuid().ToString()}.Jpeg";//保存绝对路径
            if (!Directory.Exists(Path.GetDirectoryName(webRootPath + path)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(webRootPath + path));
            }
            FileStream fs = new FileStream(savepath, FileMode.OpenOrCreate);
            BinaryWriter w = new BinaryWriter(fs);
            w.Write(ms.ToArray());
            fs.Close();
            ms.Close();
            var url = savepath.Split(new string[] { "wwwroot" }, StringSplitOptions.None)[1];
            return url;
        }

        public async Task<string> DownLoadQrCodeDataAsync(IdInputDTO input)
        {
            string id = input.id;
            string QrCodelUrl = string.Empty;
            //获取该叶片最新的二维码地址
            var model = await Db.GetIQueryable<MEGA_LeafBladeAndQrCode>().Where(x => x.LBId.Equals(id)).OrderByDescending(x => x.CreateTime).FirstOrDefaultAsync();
            if (model != null)
            {
                QrCodelUrl = model.QrCode;
            }
            else
            {
                throw new Exception("该叶片二维码不存在!");
            }

            return QrCodelUrl;
        }

        public async Task<string> GetTheQrCodeDataAsync(IdInputDTO input)
        {
            string id = input.id;
            string QrCodelUrl = string.Empty;
            var model = await Db.GetIQueryable<MEGA_LeafBladeAndQrCode>().Where(x => x.LBId.Equals(id)).OrderByDescending(x => x.CreateTime).FirstOrDefaultAsync();
            if (model != null)
            {
                QrCodelUrl = model.QrCode;
            }
            else
            {
                throw new Exception("该叶片二维码不存在!");
            }

            return QrCodelUrl;
        }

        public async Task<object> GetQrCodeByIdDataAsync(IdInputDTO input)
        {
            List<MEGA_QrCodeDTO> dataList = new List<MEGA_QrCodeDTO>();
            MEGA_QrCodeDTO datamodel = new MEGA_QrCodeDTO();
            string id = input.id; //叶片id

            #region---------【叶片信息】---------------
            var Leafmodel = await Db.GetIQueryable<MEGA_LeafBlade>().Where(x => x.Id.Equals(id)).FirstOrDefaultAsync();
            if (Leafmodel != null)
            {
                Leafmodel.Num = "1";
                datamodel.Leafmodel = Leafmodel;
            }
            else
            {
                throw new Exception("该叶片暂未绑定相关材料信息!");
            }
            #endregion

            #region---------【加工厂信息】---------------
            var LAndFmodel = await Db.GetIQueryable<MEGA_LeafBladeAndFactory>().Where(x => x.LBId.Equals(id)).FirstOrDefaultAsync();
            if (LAndFmodel != null)
            {
                var Factorymodel = await Db.GetIQueryable<MEGA_FactoryManagement>().Where(e => e.Id.Equals(LAndFmodel.FId)).FirstOrDefaultAsync();
                datamodel.Factorymodel = Factorymodel;
            }
            else
            {
                throw new Exception("该叶片暂未绑定加工厂信息!");
            }
            #endregion

            #region--------【加工人信息】------------
            List<MEGA_Worker> WorkerList = new List<MEGA_Worker>();
            //查询出与该叶片相关的所有员工id
            var workerIds = Db.GetIQueryable<MEGA_LeafBladeAndWorker>().Where(x => x.LBId.Equals(id)).Select(e => e.WId);
            foreach (var wid in workerIds)
            {
                var workermodel = await Db.GetIQueryable<MEGA_Worker>().Where(f => f.Id.Equals(wid)).FirstOrDefaultAsync();
                WorkerList.Add(workermodel);
            }
            datamodel.WorkerList = WorkerList;
            #endregion

            #region---------【油漆信息】-------------

            List<MEGA_Material> MaterialList = new List<MEGA_Material>();
            //查询出与该叶片相关的所有员工id
            var materiallist = Db.GetIQueryable<MEGA_LeafBladeAndMaterial>().Where(x => x.LBId.Equals(id)).ToList();
            foreach (var model in materiallist)
            {
                var materialmodel = await Db.GetIQueryable<MEGA_Material>().Where(f => f.Id.Equals(model.MId)).FirstOrDefaultAsync();
                materialmodel.Num = model.Num.ToString();
                MaterialList.Add(materialmodel);
            }
            datamodel.MaterialList = MaterialList;

            #endregion

            dataList.Add(datamodel);

            return dataList;
        }

        #endregion

        #region 私有成员

        #endregion
    }
}